<template>
  <div>
    <a-row>
      <a-col :span="24">
        <h4><b>审批人设置</b></h4>

        <a-radio-group v-model:value="dataType" @change="changeDataType">
          <a-radio value="USERS">指定用户</a-radio>
          <a-radio value="ROLES">角色</a-radio>
          <a-radio value="DEPTS">部门</a-radio>
          <a-radio value="INITIATOR">发起人</a-radio>
        </a-radio-group>
      </a-col>
    </a-row>

    <a-row>
      <a-col :span="24">
        <div v-if="dataType === 'USERS'">
          {{ selectedUser }}
          <a-tag v-for="(userText, index) in selectedUser.text" :key="userText" closable @close="handleClose(index)">
            {{ userText }}
          </a-tag>
          <div class="element-drawer__button">
            <a-button size="small" type="primary" @click="onSelectUsers">
              <template #icon><plus-outlined /></template>
              添加用户
            </a-button>
          </div>
        </div>

        <div v-if="dataType === 'ROLES'">
          <a-select v-model:value="roleIds" mode="multiple" placeholder="请选择角色" style="width: 100%" @change="changeSelectRoles">
            <a-select-option v-for="item in roleOptions" :key="item.roleId" :value="`ROLE${item.roleId}`" :disabled="item.status === 1">
              {{ item.roleName }}
            </a-select-option>
          </a-select>
        </div>

        <div v-if="dataType === 'DEPTS'">
          <div>
            <a-tree-select
              v-model:value="deptIds"
              ref="deptTree"
              style="width: 300px"
              :tree-data="deptTreeData"
              :field-names="deptProps"
              :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
              placeholder="请选择部门"
              tree-default-expand-all
              @select="handleDeptClick"
            />
          </div>

          <div v-if="deptIds">
            <a-radio-group v-model:value="deptType" @change="handleDeptType">
              <a-radio value="allPerson">所有人</a-radio>
              <a-radio value="designatedPerson">指定人</a-radio>
            </a-radio-group>
          </div>

          <div v-if="deptType === 'designatedPerson'">
            <a-radio-group v-model:value="deptOption" @change="handleDeptOption">
              <a-radio value="LEADER">部门负责人</a-radio>
              <a-radio value="ROLE">角色</a-radio>
            </a-radio-group>
          </div>

          <div v-if="deptOption === 'ROLE'">
            <a-select v-model:value="deptRoleId" size="small" placeholder="请选择角色" style="width: 100%" @change="changeDeptRole">
              <a-select-option v-for="item in roleOptions" :key="item.roleId" :value="`ROLE${item.roleId}`" :disabled="item.status === 1">
                {{ item.roleName }}
              </a-select-option>
            </a-select>
          </div>
        </div>
      </a-col>
    </a-row>

    <a-divider />
    <h4><b>按钮权限</b></h4>
    <a-checkbox-group v-model:value="selectButton" @change="handleButtonPermissions">
      <a-checkbox value="complete">通过</a-checkbox>
      <a-checkbox value="delegate">委托</a-checkbox>
      <a-checkbox value="addSign">加签</a-checkbox>
      <a-checkbox value="transfer">转办</a-checkbox>
      <a-checkbox value="return">退回</a-checkbox>
      <a-checkbox value="reject">拒绝</a-checkbox>
    </a-checkbox-group>

    <a-row>
      <div v-show="showMultiFlog">
        <a-divider />
        <h4><b>多实例审批方式</b></h4>
        <a-row>
          <a-radio-group v-model:value="multiLoopType" @change="changeMultiLoopType">
            <a-row>
              <a-radio value="Null">无</a-radio>
            </a-row>
            <a-row>
              <a-radio value="SequentialMultiInstance">会签（需所有审批人同意）</a-radio>
            </a-row>
            <a-row>
              <a-radio value="SequentialMultiInstancePercentageSetting">会签（手动设置百分比)</a-radio>
              <a-input v-model:value="percentage" @change="changeMultiLoopType" placeholder="请输入百分比" style="width: 100px">
                <template #suffix>%</template>
              </a-input>
            </a-row>
            <a-row>
              <a-radio value="ParallelMultiInstance">或签（一名审批人同意即可）</a-radio>
            </a-row>
          </a-radio-group>
        </a-row>
        <a-row v-if="multiLoopType !== 'Null'">
          <a-tooltip placement="topLeft" title="开启后，实例需按顺序轮流审批">
            <info-circle-outlined class="info-icon" />
          </a-tooltip>
          <span class="custom-label">顺序审批：</span>
          <a-switch v-model:checked="isSequential" @change="changeMultiLoopType" />
        </a-row>
      </div>
    </a-row>

    <!-- 候选用户弹窗 -->
    <a-modal v-model:open="userOpen" title="候选用户" width="60%" :destroy-on-close="true">
      <a-row :gutter="20">
        <!--部门数据-->
        <a-col :span="7">
          <a-card :bordered="false" style="height: 100%">
            <template #title>部门列表</template>

            <a-input v-model:value="deptName" placeholder="请输入部门名称" allow-clear size="small" style="margin-bottom: 20px">
              <template #prefix>
                <search-outlined />
              </template>
            </a-input>

            <a-tree
              v-if="deptOptions.length > 0"
              :tree-data="deptOptions"
              :fieldNames="deptProps"
              :expand-on-click-node="false"
              :defaultExpandAll="true"
              v-model:selectedKeys="selectedDeptKeys"
              ref="tree"
              default-expand-all
              @select="handleNodeClick"
            />
          </a-card>
        </a-col>
        <a-col :span="17">
          <a-table
            ref="multipleTable"
            :data-source="userTableList"
            :columns="userColumns"
            :row-key="(record) => record.employeeId"
            :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: handleSelectionChange }"
            :scroll="{ y: 600 }"
            bordered
          />
          <a-pagination v-model:current="queryParams.pageNum" v-model:pageSize="queryParams.pageSize" :total="userTotal" @change="getUserList" />
        </a-col>
      </a-row>
      <template #footer>
        <a-button type="primary" @click="handleTaskUserComplete">确 定</a-button>
        <a-button @click="userOpen = false">取 消</a-button>
      </template>
    </a-modal>
  </div>
</template>

<script>
  import { PlusOutlined, SearchOutlined, InfoCircleOutlined } from '@ant-design/icons-vue';
  import { message } from 'ant-design-vue';
  import { userApi } from '/@/api/system/user-api';
  import { roleApi } from '/@/api/system/role-api';

  // import TreeSelect from '/@/components/TreeSelect';

  const userTaskForm = {
    'flowable:dataType': '',
    assignee: '',
    ['flowable:candidateUsers']: '',
    candidateGroups: '',
    'flowable:text': '',
    'flowable:buttonPermissions': '',
    // dueDate: '',
    // followUpDate: '',
    // priority: ''
  };

  export default {
    name: 'UserTask',
    props: {
      id: String,
      type: String,
    },
    components: {
      PlusOutlined,
      SearchOutlined,
      InfoCircleOutlined,
    },
    data() {
      return {
        loading: false,
        dataType: 'USERS',
        selectedUser: {
          ids: [],
          text: [],
        },
        buttonMap: {
          complete: '通过',
          delegate: '委托',
          transfer: '转办',
          return: '退回',
          reject: '拒绝',
        },
        buttonList: ['complete', 'delegate', 'transfer', 'return', 'reject'],
        selectButton: ['complete', 'delegate', 'transfer', 'return', 'reject'],
        userOpen: false,
        deptName: undefined,
        deptOptions: [],
        deptProps: {
          key: 'departmentId',
          value: 'departmentId',
          id: 'departmentId',
          children: 'children',
          label: 'name',
          title: 'name',
        },
        selectedDeptKeys: [1],
        deptTempOptions: [],
        userTableList: [],
        userColumns: [
          {
            title: '姓名',
            dataIndex: 'actualName',
          },
          {
            title: '部门',
            dataIndex: 'departmentName',
          },
        ],
        userTotal: 0,
        selectedUserDate: [],
        roleOptions: [],
        roleIds: [],
        deptRoleId: undefined,
        deptTreeData: [],
        deptIds: undefined,

        deptType: 'allPerson',
        deptOption: undefined,
        // 查询参数
        queryParams: {
          departmentId: 1,
          pageNum: 1,
          pageSize: 10,
          disabledFlag: false,
        },
        showMultiFlog: false,
        isSequential: false,
        multiLoopType: 'Null',
        percentage: 100,
      };
    },
    watch: {
      id: {
        immediate: true,
        handler() {
          this.bpmnElement = window.bpmnInstances.bpmnElement;
          this.$nextTick(() => this.resetTaskForm());
        },
      },
      // 根据名称筛选部门树
      deptName(val) {
        this.$refs.tree.filter(val);
      },
    },
    beforeUnmount() {
      this.bpmnElement = null;
    },
    methods: {
      handleButtonPermissions() {
        userTaskForm['flowable:buttonPermissions'] = this.selectButton.join(',');
        this.updateElementTask();
      },
      handleDeptType() {
        if (this.deptType === 'allPerson') {
          userTaskForm['flowable:dataType'] = 'DEPTS';
          userTaskForm.candidateGroups = this.deptIds;
          this.updateElementTask();
          this.changeMultiLoopType();
        }
      },

      handleDeptOption() {
        if (this.deptOption === 'LEADER') {
          userTaskForm['flowable:dataType'] = 'DEPT_LEADER';
          userTaskForm.candidateGroups = this.deptIds + '_LEADER';
          this.updateElementTask();
          this.changeMultiLoopType();
        } else {
          userTaskForm['flowable:dataType'] = 'DEPTS';
          userTaskForm.candidateGroups = null;
          this.updateElementTask();
          this.changeMultiLoopType();
        }
      },
      changeDeptRole() {
        userTaskForm['flowable:dataType'] = 'DEPT_ROLE';
        userTaskForm.candidateGroups = `${this.deptIds}_${this.deptRoleId}`;
        this.updateElementTask();
        this.changeMultiLoopType();
      },
      handleDeptClick(val) {},
      resetTaskForm() {
        const bpmnElementObj = this.bpmnElement?.businessObject;
        if (!bpmnElementObj) {
          return;
        }
        console.log('bpmnElementObj', bpmnElementObj);
        console.log('dataType', bpmnElementObj.$attrs['flowable:dataType']);
        console.log('assignee', bpmnElementObj.assignee);

        this.clearOptionsData();
        this.dataType = bpmnElementObj.$attrs['flowable:dataType'];
        let buttonPermissions = bpmnElementObj.$attrs['flowable:buttonPermissions'] || [];
        if (buttonPermissions && buttonPermissions.length > 0) {
          this.selectButton = buttonPermissions.split(',');
        } else {
          this.selectButton = ['complete', 'delegate', 'transfer', 'return', 'reject'];
        }

        if (this.dataType === 'USERS') {
          let userIdData = bpmnElementObj['candidateUsers'] || bpmnElementObj['assignee'];
          let userText = bpmnElementObj['$attrs']['flowable:text'] || [];
          if (userIdData && userIdData.toString().length > 0 && userText && userText.length > 0) {
            this.selectedUser.ids = userIdData?.toString().split(',');
            this.selectedUser.text = userText?.split(',');
          }
          if (this.selectedUser.ids.length > 1) {
            this.showMultiFlog = true;
          }
          console.log('selectedUser', this.selectedUser);
        } else if (this.dataType === 'ROLES') {
          this.getRoleOptions();
          let roleIdData = bpmnElementObj['candidateGroups'] || [];
          if (roleIdData && roleIdData.length > 0) {
            this.roleIds = roleIdData.split(',');
          }
          this.showMultiFlog = true;
        } else if (this.dataType === 'DEPTS' || this.dataType === 'DEPT_LEADER' || this.dataType === 'DEPT_ROLE') {
          this.getDeptTreeData();
          this.getRoleOptions();
          let deptIdData = bpmnElementObj['candidateGroups'];
          this.deptType = 'designatedPerson';
          if (this.dataType === 'DEPT_LEADER') {
            this.deptIds = deptIdData.split('_')[0];
            this.deptOption = 'LEADER';
          } else if (this.dataType === 'DEPT_ROLE') {
            this.deptIds = deptIdData.split('_')[0];
            this.deptOption = 'ROLE';
            this.deptRoleId = deptIdData.split('_')[1];
          } else {
            this.deptIds = deptIdData;
            this.deptOption = 'allPerson';
          }
          this.dataType = 'DEPTS';
          this.showMultiFlog = true;
        }
        this.getElementLoop(bpmnElementObj);
      },
      /**
       * 清空选项数据
       */
      clearOptionsData() {
        this.selectedUser.ids = [];
        this.selectedUser.text = [];
        this.roleIds = [];
        this.deptIds = '';
      },
      /**
       * 跟新节点数据
       */
      updateElementTask() {
        const taskAttr = Object.create(null);
        for (let key in userTaskForm) {
          if (userTaskForm[key]) {
            taskAttr[key] = userTaskForm[key];
          } else {
            taskAttr[key] = undefined;
          }
        }
        window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr);
      },
      /**
       * 查询部门下拉树结构
       */
      getDeptOptions() {
        return new Promise((resolve, reject) => {
          if (!this.deptOptions || this.deptOptions.length <= 0) {
            userApi.deptTreeSelect().then((response) => {
              console.log('response,', response);
              this.deptTempOptions = response.data;
              this.deptOptions = response.data;
              resolve();
            });
          } else {
            reject();
          }
        });
      },
      /**
       * 查询部门下拉树结构（含部门前缀）
       */
      getDeptTreeData() {
        return new Promise((resolve, reject) => {
          if (!this.deptTreeData || this.deptTreeData.length <= 0) {
            this.getDeptOptions()
              .then(() => {
                this.deptTreeData = this.deptOptions;
                console.log('deptTreeData', this.deptTreeData);

                resolve();
              })
              .catch((e) => {
                console.log('deptTreeData error', e);
                reject();
              });
          } else {
            resolve();
          }
        });
      },
      /**
       * 查询部门下拉树结构
       */
      getRoleOptions() {
        if (!this.roleOptions || this.roleOptions.length <= 0) {
          roleApi.queryAll().then((response) => (this.roleOptions = response.data));
        }
      },
      /** 查询用户列表 */
      async getUserList() {
        const { data } = await userApi.listUser(this.queryParams);
        this.userTableList = data.list;
        this.userTotal = data.total;
      },
      // 筛选节点
      filterNode(value, data) {
        if (!value) return true;
        return data.label.indexOf(value) !== -1;
      },
      // 节点单击事件
      handleNodeClick(data) {
        console.log('data', data);
        this.queryParams.departmentId = data[0];
        this.getUserList();
      },
      // 关闭标签
      handleClose(index) {
        this.selectedUserDate.splice(index, 1);
        this.handleTaskUserComplete();
      },
      // 多选框选中数据
      handleSelectionChange(keys, rows) {
        console.log('keys', keys);
        console.log('rows', rows);
        this.selectedUserDate = rows;
      },
      onSelectUsers() {
        this.selectedUserDate = [];
        this.$refs.multipleTable?.clearSelection();
        this.userOpen = true;
        this.getDeptOptions();
        this.selectedDeptKeys = [1];
        this.queryParams.departmentId = 1;
        this.getUserList();
      },
      handleTaskUserComplete() {
        userTaskForm['flowable:dataType'] = 'USERS';
        userTaskForm.candidateUsers = '';
        this.selectedUser.text = this.selectedUserDate.map((k) => k.actualName) || [];
        if (this.selectedUserDate.length === 1) {
          let data = this.selectedUserDate[0];
          userTaskForm.assignee = data.employeeId;
          userTaskForm['flowable:text'] = data.actualName;
          userTaskForm.candidateUsers = null;
          this.showMultiFlog = false;
          this.multiLoopType = 'Null';
          this.changeMultiLoopType();
        } else {
          userTaskForm.candidateUsers = this.selectedUserDate.map((k) => k.employeeId).join() || null;
          userTaskForm['flowable:text'] = this.selectedUserDate.map((k) => k.actualName).join() || null;
          userTaskForm.assignee = null;
          this.showMultiFlog = true;
        }
        this.updateElementTask();
        this.userOpen = false;
      },
      changeSelectRoles(val) {
        let groups = null;
        let text = null;
        if (this.roleIds && this.roleIds.length > 0) {
          userTaskForm['flowable:dataType'] = 'ROLES';
          groups = val.join() || null;
          let textArr = this.roleOptions.filter((k) => this.roleIds.indexOf(`ROLE${k.roleId}`) >= 0);
          text = textArr?.map((k) => k.roleName).join() || null;
        } else {
          userTaskForm['flowable:dataType'] = null;
          this.multiLoopType = 'Null';
        }
        userTaskForm.candidateGroups = groups;
        userTaskForm['flowable:text'] = text;
        this.updateElementTask();
        this.changeMultiLoopType();
      },
      checkedDeptChange(checkedIds) {
        let groups = null;
        let text = null;
        this.deptIds = checkedIds;
        if (checkedIds && checkedIds.length > 0) {
          userTaskForm['flowable:dataType'] = 'DEPTS';
          groups = checkedIds.join() || null;
          let textArr = [];
          let treeStarkData = JSON.parse(JSON.stringify(this.deptTreeData));
          checkedIds.forEach((id) => {
            let stark = [];
            stark = stark.concat(treeStarkData);
            while (stark.length) {
              let temp = stark.shift();
              if (temp.children) {
                stark = temp.children.concat(stark);
              }
              if (id === temp.id) {
                textArr.push(temp);
              }
            }
          });
          text = textArr?.map((k) => k.label).join() || null;
        } else {
          userTaskForm['flowable:dataType'] = null;
          this.multiLoopType = 'Null';
        }
        userTaskForm.candidateGroups = groups;
        userTaskForm['flowable:text'] = text;
        this.updateElementTask();
        this.changeMultiLoopType();
      },
      changeDataType() {
        if (this.dataType === 'ROLES' || this.dataType === 'DEPTS' || (this.dataType === 'USERS' && this.selectedUser.ids.length > 1)) {
          this.showMultiFlog = true;
        } else {
          this.showMultiFlog = false;
        }
        this.multiLoopType = 'Null';
        this.changeMultiLoopType();
        // 清空 userTaskForm 所有属性值
        Object.keys(userTaskForm).forEach((key) => (userTaskForm[key] = undefined));
        userTaskForm['flowable:dataType'] = this.dataType;
        if (this.dataType === 'USERS') {
          if (this.selectedUser && this.selectedUser.ids && this.selectedUser.ids.length > 0) {
            if (this.selectedUser.ids.length === 1) {
              userTaskForm.assignee = this.selectedUser.ids[0];
            } else {
              userTaskForm.candidateUsers = this.selectedUser.ids.join();
            }
            userTaskForm['flowable:text'] = this.selectedUser.text?.join() || null;
          }
        } else if (this.dataType === 'ROLES') {
          this.getRoleOptions();
          if (this.roleIds && this.roleIds.length > 0) {
            userTaskForm.candidateGroups = this.roleIds.join() || null;
            let textArr = this.roleOptions.filter((k) => this.roleIds.indexOf(`ROLE${k.roleId}`) >= 0);
            userTaskForm['flowable:text'] = textArr?.map((k) => k.roleName).join() || null;
          }
        } else if (this.dataType === 'DEPTS') {
          this.getRoleOptions();
          this.getDeptTreeData();
          if (this.deptIds) {
            userTaskForm.candidateGroups = this.deptIds;
            let textArr = [];
            let treeStarkData = JSON.parse(JSON.stringify(this.deptTreeData));

            let stark = [];
            stark = stark.concat(treeStarkData);
            while (stark.length) {
              let temp = stark.shift();
              if (temp.children) {
                stark = temp.children.concat(stark);
              }
              if (this.deptIds === temp.id) {
                textArr.push(temp);
              }
            }

            userTaskForm['flowable:text'] = textArr?.map((k) => k.label).join() || null;
          }
        } else if (this.dataType === 'INITIATOR') {
          userTaskForm.assignee = '${initiator}';
          userTaskForm['flowable:text'] = '流程发起人';
        }
        this.updateElementTask();
      },
      getElementLoop(businessObject) {
        if (!businessObject.loopCharacteristics) {
          this.multiLoopType = 'Null';
          return;
        }
        this.isSequential = businessObject.loopCharacteristics.isSequential;
        if (businessObject.loopCharacteristics.completionCondition) {
          if (businessObject.loopCharacteristics.completionCondition.body === '${nrOfCompletedInstances >= nrOfInstances}') {
            this.multiLoopType = 'SequentialMultiInstance';
          } else {
            this.multiLoopType = 'ParallelMultiInstance';
          }
        }
      },
      changeMultiLoopType() {
        // 取消多实例配置
        if (this.multiLoopType === 'Null') {
          window.bpmnInstances.modeling.updateProperties(this.bpmnElement, { loopCharacteristics: null, assignee: null });
          return;
        }
        this.multiLoopInstance = window.bpmnInstances.moddle.create('bpmn:MultiInstanceLoopCharacteristics', { isSequential: this.isSequential });
        // 更新多实例配置
        window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
          loopCharacteristics: this.multiLoopInstance,
          assignee: '${assignee}',
        });
        // 完成条件
        let completionCondition = null;
        // 会签
        if (this.multiLoopType === 'SequentialMultiInstance') {
          completionCondition = window.bpmnInstances.moddle.create('bpmn:FormalExpression', { body: '${nrOfCompletedInstances >= nrOfInstances}' });
        }
        // 或签
        if (this.multiLoopType === 'ParallelMultiInstance') {
          completionCondition = window.bpmnInstances.moddle.create('bpmn:FormalExpression', { body: '${nrOfCompletedInstances > 0}' });
        }
        // 百分比
        if (this.multiLoopType === 'SequentialMultiInstancePercentageSetting') {
          completionCondition = window.bpmnInstances.moddle.create('bpmn:FormalExpression', {
            body: '${nrOfCompletedInstances/nrOfInstances>=' + this.percentage / 100 + ' }',
          });
        }
        // 更新模块属性信息
        window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement, this.multiLoopInstance, {
          collection: '${multiInstanceHandler.getUserIds(execution)}',
          elementVariable: 'assignee',
          completionCondition,
        });
      },
    },
  };
</script>

<style scoped>
  .info-icon {
    margin-right: 8px;
    color: #555;
  }

  .custom-label {
    padding-left: 5px;
    font-weight: 500;
    font-size: 14px;
    color: #606266;
  }

  .element-drawer__button {
    margin-top: 8px;
    text-align: right;
  }

  .ant-radio-group {
    margin-bottom: 15px;
    .ant-radio {
      line-height: 28px;
    }
  }

  .ant-tag {
    margin-bottom: 10px;
    .ant-tag {
      margin-left: 10px;
    }
  }
</style>
